package cn.yunyichina.provider.pay.thread;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.yunyichina.provider.framework.data.SpringContextHandler;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.iface.entity.base.EventVo;
import cn.yunyichina.provider.iface.entity.base.LogVo;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.pay.service.HisPayfinanceService;
import cn.yunyichina.provider.pay.service.impl.FinanceServiceImpl;
import cn.yunyichina.utils.convert.JsonUtils;

/**
 * his账单及平台流水对账线程
 * Created by JoeZ on 2016/11/20.
 */
public class HisPayfinanceRunnable implements Callable<Response> {

    private Logger logger = LoggerFactory.getLogger(HisPayfinanceRunnable.class);

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private HisPayfinanceService hisPayfinanceService = SpringContextHandler.getBean(HisPayfinanceService.class);

    private String branchCode;
    private String hospitalCode;
    private String beginPayTime;
    private String endPayTime;
    private String payMode;
    private String orgId;
    private String orgName;
    
    private JSONObject jsonLog;

    public HisPayfinanceRunnable(String orgId , String orgName,String branchCode, String hospitalCode, String beginPayTime, String endPayTime, String payMode,JSONObject jsonLog) {
        this.branchCode = branchCode;
        this.hospitalCode = hospitalCode;
        this.beginPayTime = beginPayTime;
        this.endPayTime = endPayTime;
        this.payMode = payMode;
        this.orgId = orgId;
        this.orgName = orgName;
        this.jsonLog = jsonLog;
    }

    @Override
    public Response call() throws Exception {
        return inputAndCheckPayments();
    }

    /**
     * 
     * 执行过程不会有异常
     * @return reponse返回值包含mapReturn
     */
    public Response inputAndCheckPayments(){
    	FinanceServiceImpl.thLogInfo.set(jsonLog);
        Map<String,String > map = new HashMap<String,String >();
        Map<String,Object > mapReturn = new HashMap<String,Object >();
        mapReturn.put("org_id" , orgId);
        mapReturn.put("pay_time" , beginPayTime);
        mapReturn.put("is_clear_his" , "1");
        
        Response response = new Response();
        boolean isSuccess = false;
        boolean isHisDatasNull = false;
        String message = "";
        try {
			long time = new Date().getTime() / 1000;

			try {
			    //获取his账单前数据清理
			    map.put("orgId" , orgId);
			    map.put("payTime" , beginPayTime);
			    map.put("isClearHis" , "1");

			    Response restResp = hisPayfinanceService.resetHisPayfinanceInfo(JSON.toJSONString(map));
			    logger.info(orgName + "his数据清理返回结果：  " + restResp.getResultCode() + " -- " + restResp.getResultMessage());
			} catch (Exception e) {
				mapReturn.put("inputAndCheckPayments_hisClear", "his数据清理失败"+orgName);
				mapReturn.put("clear_his_data", false);
			    logger.error("[HisPayfinanceRunnable.inputAndCheckPayments].his数据清理失败！", e);
			}


			logger.info("<<<<< HisPayfinanceRunnable."+ orgName +"开始时间:" + sdf.format(new Date()));
			map = new HashMap<String,String >();
			
			map.put("branchCode", branchCode);
			map.put("hospitalCode", hospitalCode);
			map.put("beginPayTime", beginPayTime + " 00:00:00"); //应项目要求修改账单拉取时间规则
			map.put("endPayTime", beginPayTime + " 23:59:59");
			map.put("payMode", payMode);
			map.put("orgId", orgId);
			map.put("orgName", orgName);

			logger.info(orgName +"<<<<< HisPayfinanceRunnable.请求前置机时间:" + ((new Date().getTime() / 1000) - time));

			Response resp = hisPayfinanceService.getHisPayfinanceInfo(JSON.toJSONString(map));
			logger.info(JsonUtils.toJsonString(resp));
			response.setResult(orgId);
			message =  resp.getResultMessage();
			logger.info(orgName + "his数据返回结果：  " + JsonUtils.toJsonString(resp));
			logger.info("<<<<< HisPayfinanceRunnable."+ orgName +"结束时间:" + ((new Date().getTime() / 1000) - time));
			if ("0".equals(resp.getResultCode())) {
				isSuccess = true;
			}else {
				if("4001".equals(resp.getResultCode())){  //his返回无数据
					isSuccess = true;
					isHisDatasNull = true;
				}else{
					isSuccess = false;
				}
			}
 			
		} catch (Exception e) {
			isSuccess = false;
			logger.error("拉取HIS数据发生异常",e);
		}
        if (isSuccess) {
        	response.setResultCodeAndMessage("0", "拉取HIS数据成功,message:" + message);
        }
        else {
        	if (StringUtils.isNotBlank(message)) {
        		response.setResultCodeAndMessage("-1",message);
        	}
        	else {
        		message = "拉取HIS数据失败";
        		response.setResultCodeAndMessage("-1", message);
        	}
        	
        }
        mapReturn.put("is_success", isSuccess);
        mapReturn.put("check_data_type","his");
        response.setResult(JsonUtils.toJsonString(mapReturn));
        
        if ( !isSuccess) {
        	//事件信息
            Map<String,Object> paramEvent = new HashMap<>();
        	paramEvent.put("event_code", "CK_PULL_HIS_BILL");
        	paramEvent.put("module_code", "CHECK_ACCOUNT");
        	Response responseEvent = BaseService.callHumpFromInternal("yyt.base.event.get", JsonUtils.toJsonString(paramEvent));
        	if (StringUtils.isNotBlank(responseEvent.getResult())) {
        		EventVo event = JsonUtils.parseObject(responseEvent.getResult(), EventVo.class);
        		FinanceServiceImpl.sendSmsForFail(orgId,"CK_PULL_HIS_BILL", null, beginPayTime, FinanceServiceImpl.YYYYMMDDHHMISS14.format(new Date()),event.getEventLevel()+"","拉取HIS数据失败");
        	}
        	else {
        		logger.error("获取系统事件定义事事件失败！，无法获取事件级别：CK_PULL_HIS_BILL");
        		FinanceServiceImpl.sendSmsForFail(orgId,"CK_PULL_HIS_BILL",null, beginPayTime, FinanceServiceImpl.YYYYMMDDHHMISS14.format(new Date()),"-1","拉取HIS数据失败");
        	}
        	FinanceServiceImpl.insertLog(orgId,"CK_PULL_HIS_BILL",message);
        }else{
			if(isHisDatasNull){
				//插入his无数据但执行成功事件
				logger.info("his无数据但执行成功事件 isHisDatasNull:" + isHisDatasNull + ",hospitalName:" + orgName);
			}
		}

		logger.info(orgName + "最终处理his数据返回结果：  " + JsonUtils.toJsonString(response));
        return response;
    }
}
